package com.siwei.mes.upload.erp;

import com.alibaba.fastjson.JSONObject;
import com.siwei.mes.common.util.JsonUtils;
import com.siwei.mes.service.erp.RwdextraExtendService;
import com.siwei.mes.upload.erp.config.ErpConfig;
import com.siwei.mes.upload.erp.entity.ErpAddTaskPhbLog;
import com.siwei.mes.upload.erp.entity.ErpPhbInfo;
import com.siwei.mes.upload.erp.entity.ErpResultBody;
import com.siwei.mes.upload.erp.entity.ErpWbcheckinfo;
import com.siwei.mes.upload.erp.vo.ErpPhbVo;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

import static com.siwei.mes.common.exception.handler.MessageHandler.assertTrue;

/**
 * 上传到ERP
 *
 * @Description: 上传到ERP
 * @Version: 1.0
 * @author: mlchen
 * @date: 2024/8/22 17:08
 */
@Service
public class UploadErpService {
    private static final Logger log = LoggerFactory.getLogger("erp");

    @Resource
    private ErpConfig erpConfig;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RwdextraExtendService rwdextraExtendService;

    /**
     * 生成hash值
     *
     * @param input
     * @return
     */
    public String generateMD5Hash(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return new String(Hex.encodeHex(hashBytes));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取访问地址
     *
     * @param path 接口名称
     * @return
     */
    public String getUrlPath(String path) {
        long timeMillis = System.currentTimeMillis() / 1000;
        String dataToHash = path + timeMillis + erpConfig.getSalt();
        String sign = this.generateMD5Hash(dataToHash);
        return erpConfig.getAddress() + path + "?sign=" + sign + "&rTime=" + timeMillis;
    }

    /**
     * 获取时间戳
     *
     * @return
     */
    public Long getRTime() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 获取签名
     *
     * @param path
     * @return
     */
    public String getSign(String path, Long timeMillis) {
        String dataToHash = path + timeMillis + erpConfig.getSalt();
        return this.generateMD5Hash(dataToHash);
    }

    /**
     * 上传 磅单明细表快检批检
     *
     * @param erpWbcheckinfo 磅单明细表快检批检
     * @param isNotify       是否报错通知 true 通知 false不通知
     */
    public void uploadWbcheckInfo(ErpWbcheckinfo erpWbcheckinfo, Boolean isNotify) {
        HttpEntity httpEntity = new HttpEntity<>(erpWbcheckinfo);
        this.uploadErp(httpEntity, ErpConfigEnum.PINKONG_WBCHECKINFO, isNotify);
    }

    /**
     * 同步配比库的配比
     *
     * @param erpPhbInfo 配合比信息
     * @param isNotify   是否报错通知 true 通知 false不通知
     */
    public String uploadPhbInfo(ErpPhbInfo erpPhbInfo, Boolean isNotify) {
        HttpEntity httpEntity = new HttpEntity(erpPhbInfo);
        String resultInfo = this.uploadErp(httpEntity, ErpConfigEnum.PINKONG_PHBFROMPK, isNotify);
        ErpPhbVo erpPhbVo = JsonUtils.getObject(resultInfo, ErpPhbVo.class);
        if (erpPhbVo != null) {
            return erpPhbVo.getPhbId();
        }
        return null;
    }


    /**
     * 上传配合比调整日志
     *
     * @param erpAddTaskPhbLog 配合比调整日志
     * @param isNotify         是否报错通知 true 通知 false不通知
     */
    public String uploadAddTaskPhbLog(ErpAddTaskPhbLog erpAddTaskPhbLog, Boolean isNotify) {
        /** 加入修改配合比操作*/
        rwdextraExtendService.setRwdextraPrintInfoPhb(erpAddTaskPhbLog);
        Long rTime = this.getRTime();
        String sign = this.getSign(ErpConfigEnum.PINKONG_ADDTASKPHBLOG.getPath(), rTime);
        erpAddTaskPhbLog.setRTime(rTime);
        erpAddTaskPhbLog.setSign(sign);
        erpAddTaskPhbLog.setOperator("MES");
        HttpEntity httpEntity = new HttpEntity(erpAddTaskPhbLog);
        return this.uploadErp(httpEntity, ErpConfigEnum.PINKONG_ADDTASKPHBLOG, isNotify);
    }

    /**
     * @param httpEntity    发送的参数
     * @param erpConfigEnum erp接口枚举
     * @param isNotify      是否报错通知 true 通知 false不通知
     * @return
     */
    private String uploadErp(HttpEntity httpEntity, ErpConfigEnum erpConfigEnum, Boolean isNotify) {
        String url = this.getUrlPath(erpConfigEnum.getPath());

        log.info("上传到ERP【" + erpConfigEnum.getDesc() + "】,接口地址：【" + url + "】,入参：" + JsonUtils.getJson(httpEntity.getBody()));
        /**发起请求,服务地址，请求参数，返回消息体的数据类型*/
        try {
            ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, httpEntity, JSONObject.class);
            JSONObject body = response.getBody();
            ErpResultBody erpResultBody = JsonUtils.getObject(body, ErpResultBody.class);
            if (erpResultBody == null) {
                assertTrue("ERP服务异常,请联系ERP相关人员排查");
            }
            if (erpResultBody.getCode() == HttpURLConnection.HTTP_OK) {
                log.info("上传到ERP【{}】成功,返回信息：【{}】", erpConfigEnum.getDesc(), response.getBody());
                return erpResultBody.getResult();
            } else {
                log.error("上传到ERP【{}】失败,错误信息：【{}】，入参：【{}】", erpConfigEnum.getDesc(), erpResultBody.getMessage(), JsonUtils.getJson(httpEntity.getBody()));
                assertTrue(isNotify, "上传到ERP【" + erpConfigEnum.getDesc() + "】失败,错误信息：【" + erpResultBody.getMessage() + "】");
            }
            return null;
        } catch (Exception e) {
            log.error("上传到ERP【{}】异常,错误信息：【{}】入参：【{}】", erpConfigEnum.getDesc(), e.getMessage(), JsonUtils.getJson(httpEntity.getBody()), e);
            assertTrue(isNotify, "上传到ERP【" + erpConfigEnum.getDesc() + "】异常，错误信息：【" + e.getMessage() + "】");
        }
        return null;
    }

}
